package cn.jingzhuan.element.demo.view.util.audio

import android.content.Context
import android.media.MediaPlayer
import android.os.PowerManager
import android.util.Log
import java.lang.Exception

/**
 * Created by KNOX.
 */
class AudioPlayer constructor(private val context : Context) : Playback {

  private var mediaPlayer : MediaPlayer? = null
  private var callback : Playback.Callback? = null
  private var isPrepared = false
  private var isPaused = false
  private var lastCurrentPosition = 0

  private val completeListener = MediaPlayer.OnCompletionListener {
    if (callback != null) {
      callback?.onCompelte()
    }
  }

  private var errorListener = MediaPlayer.OnErrorListener { _, _, _ ->
    isPrepared = false
    if (mediaPlayer == null) {
      initPlayer()
    }
    false
  }

  init {
    initPlayer()
  }

  companion object {
    private const val TAG = "AudioPlayer"
  }

  private fun initPlayer() {
    mediaPlayer = MediaPlayer()
    mediaPlayer?.setVolume(100f, 100f)
    mediaPlayer?.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
  }

  override fun setCompleteCallback(callback : Playback.Callback?) {
    this.callback = callback
  }

  override fun prepare(audio : Audio) {
    try {
      mediaPlayer?.setOnPreparedListener { mp ->
        isPrepared = true
        callback?.onPrepared()
        mp?.setOnCompletionListener(completeListener)
        mp?.setOnErrorListener(errorListener)
        Log.i(TAG, "AudioPlayer is prepared")
      }
      mediaPlayer?.reset()
      mediaPlayer?.setDataSource(audio.url)
      mediaPlayer?.prepareAsync()
    } catch (e : Exception) {
      callback?.onPrepareFailed(e.toString())
      e.printStackTrace()
    }

  }

  override fun start() {
    if (isPrepared && mediaPlayer != null) {
      mediaPlayer?.start()
      isPaused = false
      Log.i(TAG, "AudioPlayer is started")
    }
  }

  override fun isPlaying() : Boolean? = isPrepared && mediaPlayer?.isPlaying !!

  override fun duration() : Int? {
    if (isPrepared && mediaPlayer != null) {
      return mediaPlayer?.duration
    }
    return 0
  }

  override fun currentPosition() : Int? {
    if (isPrepared && mediaPlayer != null) {
      return mediaPlayer?.currentPosition
    }
    return 0
  }

  override fun pause() {
    if (isPrepared && mediaPlayer != null) {
      isPaused = true
      mediaPlayer?.pause()
      lastCurrentPosition = mediaPlayer?.currentPosition !!
      Log.i(TAG, "AudioPlayer is paused")
    }
  }
  
  override fun stop() {
    if (mediaPlayer != null) {
      mediaPlayer?.stop()
      Log.i(TAG, "AudioPlayer is stopped")
    }
  }

  override fun resume() {
    if (isPrepared && mediaPlayer != null && isPaused) {
//      mediaPlayer?.currentPosition?.let { mediaPlayer?.seekTo(it) }
      mediaPlayer?.seekTo(lastCurrentPosition)
      mediaPlayer?.start()
      isPaused = false
      Log.i(TAG, "AudioPlayer resume")
    }
  }
  
  override fun seekTo(second : Int) {
    if (mediaPlayer != null) {
      lastCurrentPosition = second
      mediaPlayer?.seekTo(lastCurrentPosition)
      mediaPlayer?.start()
    }
  }

  override fun release() {
    if (mediaPlayer != null) {
      mediaPlayer?.release()
      mediaPlayer = null
      Log.i(TAG, "AudioPlayer released")
    }
  }

}